﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Data.SqlClient;
using System.Text;
using Library;

namespace Library
{
    public class DBHelp
    {
        private SqlCommand cmd;
        private bool isOpen;

        //Các thuộc tính để kiểm soát lỗi và kiểm tra phiên làm việc
        private bool handleErrors;

        public bool HandleErrors
        {
            get { return handleErrors; }
            set { handleErrors = value; }
        }
        private StringBuilder strError = new StringBuilder();

        public StringBuilder StrError
        {
            get { return strError; }
            set { strError = value; }
        }
        private bool intransaction = false;

        public bool Intransaction
        {
            get { return intransaction; }
            set { intransaction = value; }
        }

        //Hàm khởi tạo DBHelp
        public DBHelp()
        {
            string cnnstr = AppEnvironment.ConnStr;
            SqlConnection conn = new SqlConnection(cnnstr);
            this.cmd = conn.CreateCommand();
        }

        public void SetCommandText(string commandText, CommandType commandType)
        {
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            cmd.Parameters.Clear();
        }

        //Thêm tham số cho câu lệnh
        public void AddParameter(SqlParameter param)
        {
            cmd.Parameters.Add(param);
        }

        //Thêm tham số với tên và giá trị
        public void AddParameter(string name, object value)
        {
            SqlParameter param = cmd.CreateParameter();
            param.ParameterName = name;
            param.Value = value;
            cmd.Parameters.Add(param);
        }

        //Thêm tham số với kiểu dữ liệu và xuất ra giá trị
        public void AddParameter(string name, object value, DbType type, ParameterDirection direction)
        {
            SqlParameter param = cmd.CreateParameter();
            param.ParameterName = name;
            param.Value = value;
            param.DbType = type;
            param.Direction = direction;
            cmd.Parameters.Add(param);
        }

        //Dọn dẹp tham số
        public void ClearParameter()
        {
            cmd.Parameters.Clear();
        }

        //Mở kết nối
        public void Open()
        {
            if (isOpen)
            {
                return;
            }
            if (this.Intransaction)
            {
                return;
            }
            if (cmd.Connection.State != ConnectionState.Open)
            {
                cmd.Connection.Open();
                isOpen = true;
            }
        }

        //Đóng kết nối
        public void Close()
        {
            cmd.Connection.Close();
            isOpen = false;
        }

        //Giải phóng tài nguyên
        public void Dispose()
        {
            cmd.Connection.Dispose();
            cmd.Dispose();
            this.Close();
        }

        //Truy xuất dữ liệu với SqlDataReader
        public SqlDataReader ExecuteReader()
        {
            SqlDataReader sdr = null;
            try
            {
                this.Open();
                sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return sdr;
        }

        //Truy xuất dữ liệu với SqlDataReader với câu lệnh và kiểu câu lệnh
        public SqlDataReader ExecuteReader(string commandText, CommandType commandType)
        {
            SqlDataReader sdr = null;
            try
            {
                this.Open();
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return sdr;
        }

        //Truy xuất dữ liệu với SqlDataReader với câu lệnh, kiểu câu lệnh và dãy tham số
        public SqlDataReader ExecuteReader(string commandText, CommandType commandType, SqlParameterCollection param)
        {
            SqlDataReader sdr = null;
            try
            {
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                cmd.Parameters.Clear();
                foreach (SqlParameter p in param)
                {
                    cmd.Parameters.Add(p);
                }
                sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return sdr;
        }

        //Thực thi câu lệnh đơn
        //Execute non query 
        public int ExecuteNonQuery()
        {
            int row = 0;
            try
            {
                this.Open();
                row = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return row;
        }

        //Thực thi câu lệnh đơn với câu lệnh và kiểu câu lệnh
        //Execute non query with command text and command type
        public int ExecuteNonQuery(string commandText, CommandType commandType)
        {
            int row = 0;
            try
            {
                this.Open();
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                row = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //throw ex;
                if (this.Intransaction)
                {
                    this.RollBack();
                }
            }
            finally
            {
                cmd.Dispose();
            }
            return row;
        }

        //Thực thi câu lệnh đơn với câu lệnh, kiểu câu lệnh và danh sách tham số
        //Execute non query with command text, command type and parameter collection
        public int ExecuteNonQuery(string commandText, CommandType commandType, SqlParameterCollection param)
        {
            int row = 0;
            try
            {
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                cmd.Parameters.Clear();
                foreach (SqlParameter p in param)
                {
                    cmd.Parameters.Add(p);
                }
                row = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return row;
        }

        //Thực thi câu lệnh đơn trả về giá trị cột đầu tiên của bản ghi đầu tiên
        //Execute scalar and return first value of first collumn
        public object ExecuteScalar()
        {
            object row = null;
            try
            {
                this.Open();
                row = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();


            }

            return row;
        }

        //Execute scalar with command text, command type and return object
        public object ExecuteScalar(string commandText, CommandType type)
        {
            object row = null;
            try
            {
                this.Open();
                cmd.CommandText = commandText;
                cmd.CommandType = type;
                row = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {

                cmd.Dispose();
            }

            return row;
        }

        //Execute scalar with command text, command type, parameter collection and return object value
        public object ExecuteScalar(string commandText, CommandType type, SqlParameterCollection parameters)
        {
            object row = null;
            try
            {
                this.Open();
                cmd.CommandText = commandText;
                cmd.CommandType = type;
                cmd.Parameters.Clear();
                foreach (SqlParameter para in parameters)
                {
                    cmd.Parameters.Add(para);
                }
                row = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }


            return row;
        }

        //Thực thi câu lệnh bằng đối tượng DataTable
        //Execute data table
        public DataTable ExecuteDataTable()
        {
            SqlDataAdapter sda = null;
            DataTable dt = new DataTable();
            try
            {
                sda.SelectCommand = this.cmd;
                sda.Fill(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return dt;
        }

        //Thực thi câu lệnh bằng đối tượng DataTable với câu lệnh và kiểu câu lệnh
        //Execute data table with command text and command type
        public DataTable ExecuteDataTable(string commandText, CommandType commandType)
        {
            SqlDataAdapter sda = null;
            DataTable dt = new DataTable();
            try
            {
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                sda = new SqlDataAdapter();
                sda.SelectCommand = this.cmd;
                sda.Fill(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return dt;
        }

        //Thực thi câu lệnh bằng đối tượng DataTable với câu lênh, kiểu câu lệnh và danh sách tham số
        //Execute data table with command text, command type and parameter collection
        public DataTable ExecuteDataTable(string commandText, CommandType commandType, SqlParameterCollection param)
        {
            SqlDataAdapter sda = null;
            DataTable dt = new DataTable();
            try
            {
                cmd.CommandText = commandText;
                cmd.CommandType = commandType;
                cmd.Parameters.Clear();
                foreach (SqlParameter p in param)
                {
                    cmd.Parameters.Add(p);
                }
                sda = new SqlDataAdapter();
                sda.SelectCommand = this.cmd;
                sda.Fill(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return dt;
        }

        //Đổ dữ liệu vào DataTable
        //Fill data into datatable
        public int Fill(DataTable dt)
        {
            int result = 0;
            try
            {
                this.Open();
                SqlDataAdapter sda = new SqlDataAdapter();
                sda.SelectCommand = cmd;
                result = sda.Fill(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
            }
            return result;
        }

        //Bắt đầu phiên làm việc
        //Begin transaction
        public void BeginTransaction()
        {
            if (this.Intransaction)
            {
                return;
            }
            if (cmd.Connection.State != ConnectionState.Open)
            {
                cmd.Connection.Open();
            }
            SqlTransaction trans = cmd.Connection.BeginTransaction();
            cmd.Transaction = trans;
            Intransaction = true;
        }

        //Bắt đầu phiên làm việc có tham số
        //Begin transaction with parameter
        public void BeginTransaction(IsolationLevel lvl)
        {
            if (this.Intransaction)
            {
                return;
            }
            if (cmd.Connection.State != ConnectionState.Open)
            {
                cmd.Connection.Open();
            }
            SqlTransaction trans = cmd.Connection.BeginTransaction(lvl);
            cmd.Transaction = trans;
            Intransaction = true;
        }

        //Thực hiện phiên làm việc
        //Commit transaction
        public void Commit()
        {
            if (Intransaction)
            {
                cmd.Transaction.Commit();
            }
            Intransaction = false;
        }

        //Thực thi không thành công và chuyển về trạng thái ban đầu
        //Operation error and rollback
        public void RollBack()
        {
            if (Intransaction)
            {
                try
                {
                    cmd.Transaction.Rollback();
                }
                catch (InvalidOperationException ioe)
                {
                    if (HandleErrors)
                    {
                        StrError.Append("Loi, quay tro lai");
                        StrError.Append(ioe.Message);
                        StrError.Append("\n");
                    }
                    this.Close();
                }
                finally
                {
                    Intransaction = false;
                }
            }
        }

        //Trả về thông báo lỗi
        //Return error string
        public string GetError()
        {
            return StrError.ToString();
        }

        //Dọn dẹp và trả về lỗi
        //Clear and return error string
        public string ClearError()
        {
            string str = StrError.ToString();
            StrError = new StringBuilder();
            return str;
        }
    }
}